import win32api
import win32con
import win32gui
import time
from typing import Tuple

class MouseManager:
    def __init__(self):
        """初始化鼠标管理器"""
        self.last_x = 0
        self.last_y = 0

    def _make_lparam(self, x: int, y: int) -> int:
        """
        将x,y坐标打包成LPARAM格式
        """
        return (y << 16) | x

    def move_to(self, hwnd: int, x: int, y: int) -> bool:
        """
        移动鼠标到指定位置（无需移动实际鼠标）
        
        Args:
            hwnd: 窗口句柄
            x: x坐标
            y: y坐标
            
        Returns:
            bool: 操作是否成功
        """
        try:
            # 保存最后的位置
            self.last_x = x
            self.last_y = y
            
            # 创建坐标参数
            lparam = self._make_lparam(x, y)
            
            # 发送鼠标移动消息
            win32gui.PostMessage(hwnd, win32con.WM_MOUSEMOVE, 0, lparam)
            return True
            
        except Exception as e:
            print(f"移动鼠标失败: {e}")
            return False

    def click(self, hwnd: int, x: int = None, y: int = None, 
             button: str = 'left', clicks: int = 1, interval: float = 0.1) -> bool:
        """
        在指定位置点击鼠标
        
        Args:
            hwnd: 窗口句柄
            x: x坐标（如果为None则使用最后移动的位置）
            y: y坐标（如果为None则使用最后移动的位置）
            button: 鼠标按键 ('left', 'right', 'middle')
            clicks: 点击次数
            interval: 点击间隔时间
            
        Returns:
            bool: 操作是否成功
        """
        try:
            # 如果没有指定坐标，使用最后的位置
            x = self.last_x if x is None else x
            y = self.last_y if y is None else y
            
            # 设置消息类型
            if button == 'left':
                down_msg = win32con.WM_LBUTTONDOWN
                up_msg = win32con.WM_LBUTTONUP
                down_wparam = win32con.MK_LBUTTON
            elif button == 'right':
                down_msg = win32con.WM_RBUTTONDOWN
                up_msg = win32con.WM_RBUTTONUP
                down_wparam = win32con.MK_RBUTTON
            elif button == 'middle':
                down_msg = win32con.WM_MBUTTONDOWN
                up_msg = win32con.WM_MBUTTONUP
                down_wparam = win32con.MK_MBUTTON
            else:
                return False

            # 创建坐标参数
            lparam = self._make_lparam(x, y)

            # 首先移动到目标位置
            self.move_to(hwnd, x, y)
            time.sleep(0.1)

            # 执行点击
            for _ in range(clicks):
                # 按下
                win32gui.PostMessage(hwnd, down_msg, down_wparam, lparam)
                time.sleep(0.1)
                
                # 释放
                win32gui.PostMessage(hwnd, up_msg, 0, lparam)
                
                if clicks > 1:
                    time.sleep(interval)

            return True

        except Exception as e:
            print(f"点击鼠标失败: {e}")
            return False

    def right_click(self, hwnd: int, x: int = None, y: int = None) -> bool:
        """
        右键点击（快捷方法）
        """
        return self.click(hwnd, x, y, button='right')

    def double_click(self, hwnd: int, x: int = None, y: int = None) -> bool:
        """
        双击（快捷方法）
        """
        return self.click(hwnd, x, y, clicks=2)

    def drag(self, hwnd: int, start_x: int, start_y: int, end_x: int, end_y: int, 
            button: str = 'left', duration: float = 0.5, steps: int = 10) -> bool:
        """
        拖拽操作
        
        Args:
            hwnd: 窗口句柄
            start_x: 起始x坐标
            start_y: 起始y坐标
            end_x: 结束x坐标
            end_y: 结束y坐标
            button: 鼠标按键
            duration: 拖拽持续时间
            steps: 移动步数
            
        Returns:
            bool: 操作是否成功
        """
        try:
            # 设置消息类型
            if button == 'left':
                down_msg = win32con.WM_LBUTTONDOWN
                up_msg = win32con.WM_LBUTTONUP
                down_wparam = win32con.MK_LBUTTON
            elif button == 'right':
                down_msg = win32con.WM_RBUTTONDOWN
                up_msg = win32con.WM_RBUTTONUP
                down_wparam = win32con.MK_RBUTTON
            else:
                return False

            # 移动到起始位置
            self.move_to(hwnd, start_x, start_y)
            time.sleep(0.1)

            # 按下鼠标
            start_lparam = self._make_lparam(start_x, start_y)
            win32gui.PostMessage(hwnd, down_msg, down_wparam, start_lparam)
            time.sleep(0.1)

            # 计算每一步的增量
            dx = (end_x - start_x) / steps
            dy = (end_y - start_y) / steps
            step_delay = duration / steps

            # 逐步移动
            for i in range(steps):
                current_x = int(start_x + dx * (i + 1))
                current_y = int(start_y + dy * (i + 1))
                self.move_to(hwnd, current_x, current_y)
                time.sleep(step_delay)

            # 释放鼠标
            end_lparam = self._make_lparam(end_x, end_y)
            win32gui.PostMessage(hwnd, up_msg, 0, end_lparam)

            return True

        except Exception as e:
            print(f"拖拽操作失败: {e}")
            return False